package embeded.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.RemoteException;
import java.util.Properties;

import javax.rmi.PortableRemoteObject;

import org.omg.CORBA.ORB;
import org.omg.PortableServer.POA;

import embeded.EmbededObject;
import embeded.EmbededObjectListener;
import embeded._EmbededObject_Stub;

public class EmbededObjectListenerImpl extends Thread implements
		EmbededObjectListener {
	private EmbededObject embededObject = null;
	private int listening_port;
	private String listening_address;
	private ORB orb = null;
	private POA poa = null;

	public EmbededObjectListenerImpl(EmbededObject embededObject, ORB orb,
			POA poa) {
		this.embededObject = embededObject;
		this.orb = orb;
		this.poa = poa;
	}

	@Override
	public void run() {
		super.run();
		doListening();
	}

	private void doListening() {
		String iorSender = null;
		loadProperties();
		try {
			embededObject.getTextfield().append(
					"Listener : listening sussesfull\n");
			MulticastSocket sender = new MulticastSocket(listening_port);
			InetAddress group = InetAddress.getByName(listening_address);
			sender.joinGroup(group);
			byte[] byteIor;
			while (true) {
				byteIor = new byte[1024];
				DatagramPacket reader = new DatagramPacket(byteIor,
						byteIor.length);
				sender.receive(reader);
				iorSender = new String(byteIor).trim();
			//	System.out.println(iorSender);

				org.omg.CORBA.Object objet = orb.string_to_object(iorSender);

				EmbededObject embeded = (EmbededObject) PortableRemoteObject
						.narrow(objet, EmbededObject.class);

				if (!this.embededObject.equalsEmbeded(embeded)) {
					_EmbededObjectImpl_Tie tie = new _EmbededObjectImpl_Tie();
					tie.setTarget(this.embededObject);
					try {
						org.omg.CORBA.Object obj = this.poa
								.servant_to_reference(tie);
						EmbededObject emb = (EmbededObject) PortableRemoteObject
								.narrow(obj, EmbededObject.class);
						embeded.registerEmbededObjects(emb, this.embededObject.getAllTopic());
						this.embededObject
								.registerEmbededObjects(embeded, null);
					} catch (Exception e) {
						embededObject.getTextfield().append(
								"Listener : error saving neighbor\n");
						e.printStackTrace();
					}
				}
			}
		} catch (IOException e) {
			try {
				embededObject.getTextfield().append(
						"Listener : error listening\n");
			} catch (RemoteException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
	}

	private boolean loadProperties() {
		Properties prop = new Properties();
		String path = new File(".").getAbsolutePath();
		path = path.substring(0, path.length() - 1);
		try {
			prop.load(new FileInputStream(path + "conf\\properties.properties"));
			listening_port = Integer.parseInt(prop
					.getProperty("EMBEDED_LISTENING_PORT"));
			listening_address = prop.getProperty("EMBEDED_LISTENING_ADDRESS");
		} catch (Exception e) {
			try {
				embededObject.getTextfield().append(
						"Listener : Error getting properties from file\n");
			} catch (RemoteException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public void startListening() {
		this.start();
	}

	public void stopListening() {
		this.stop();
	}

}
